package com.gking.centerSystem.service.Routes;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gking.centerSystem.common.BaseContext;
import com.gking.centerSystem.common.ProgramException;
import com.gking.centerSystem.common.Result;
import com.gking.centerSystem.entity.Routes;
import com.gking.centerSystem.entity.Sort;
import com.gking.centerSystem.mapper.RoutesMapper;
import com.gking.centerSystem.service.Sort.SortService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class RoutesServiceImpl extends ServiceImpl<RoutesMapper, Routes> implements RoutesService {

    @Resource
    private SortService sortService;

    @Resource
    private RoutesMapper routesMapper;

    /**
     * 通过一个分类id找出该分类下的所有分类id
     *
     * @param id 分类id
     * @return s
     */
    private List<String> getIds(String id) {
        List<String> idList = new ArrayList<>();
        idList.add(id);

        // 将分类下的所有权限分类id查找出来
        LambdaQueryWrapper<Sort> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Sort::getParentId, id);
        queryWrapper.eq(Sort::getIsDelete, 0);
        queryWrapper.eq(Sort::getType, "page");
        List<Sort> sorts = sortService.list(queryWrapper);

        // 递归找出所有id
        for (Sort sort : sorts) idList.addAll(getIds(sort.getId()));
        return idList;
    }

    /**
     * 获取页面路由列表
     *
     * @param sortId 分类id
     * @param size   分页大小
     * @param page   分页页码
     * @return s
     */
    @Override
    public Result<Page> getRoutesList(String sortId, Integer size, Integer page) {

        if (page == null || size == null) return Result.error("分页参数错误！");

        try {
            List<String> ids = Collections.emptyList();
            if (sortId != null) { //是否为条件查询
                ids = new ArrayList<>(new HashSet<>(getIds(sortId)));
            }

            Page<Routes> pageInfo = new Page<>(page, size);
            Page<Routes> pageResult;
            ids.removeIf(id -> id == null || id.trim().isEmpty());
            if (ids.isEmpty()) {
                pageResult = routesMapper.getRoutesList(pageInfo);
            } else {
                pageResult = routesMapper.getRoutesListBySort(pageInfo, ids);
            }

            return Result.success("获取角色列表成功！", pageResult);
        } catch (Exception e) {
            log.error("获取角色列表失败！{}", e.getMessage());
            throw new ProgramException();
        }
    }


    /**
     * 获取分类下的所有路由
     *
     * @param sortId 分类id
     * @return s
     */
    @Override
    public Result<List<Routes>> getAllSortRoutes(String sortId) {
        if (Objects.equals(sortId, "")) return Result.error("请将参数补充完整！");

        try {
            List<String> ids = new ArrayList<>(new HashSet<>(getIds(sortId)));
            LambdaQueryWrapper<Routes> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Routes::getIsDelete, 0);
            wrapper.in(Routes::getSortId, ids);
            wrapper.orderByDesc(Routes::getCreateTime);

            List<Routes> list = this.list(wrapper);
            return Result.success("获取分类下的所有路由成功！", list);
        } catch (Exception e) {
            log.error("获取分类下的所有路由失败！{}", e.getMessage());
            throw new ProgramException();
        }
    }


    /**
     * 创建页面路由或者修改页面路由信息
     *
     * @param route 路由信息
     * @return s
     */
    @Override
    public Result<String> setRoute(Routes route) {

        String path = route.getPath();
        String name = route.getName();
        String component = route.getComponent();
        String componentPath = route.getComponentPath();
        String description = route.getDescription();
        Integer isRedirect = route.getIsRedirect();
        String sortId = route.getSortId();
        Integer isNavigation = route.getIsNavigation();

        String routeId = route.getId(); // 可选参数，修改路由时可带上，创建时无需
        String parentId = route.getParentId();


        if (name.isEmpty() || path.isEmpty() || component.isEmpty() || componentPath.isEmpty() || sortId.isEmpty())
            return Result.error("请将参数补充完整");

        if (Objects.equals(routeId, "")) routeId = null;
        if (Objects.equals(parentId, "")) parentId = null;
        if (isRedirect != null && isRedirect != 0 && isRedirect != 1)
            return Result.error("isRedirect参数错误");

        try {
            Sort s = sortService.getById(sortId);
            if (s == null) return Result.error("分类不存在！");
            if (!Objects.equals(s.getType(), "page")) return Result.error("该分类不是页面分类！");


            int level = 1;
            // 如果路由父级id存在
            if (parentId != null) {
                Routes parentRoute = this.getById(parentId);
                if (parentRoute == null) return Result.error("父级路由不存在！");
                if (parentRoute.getSortId() != null && sortId != null && !getIds(parentRoute.getSortId()).contains(sortId)) {
                    return Result.error("父级路由分类和创建的路由分类不属于同一系分类！");
                }
                level = parentRoute.getLevel() + 1;
            }

            if (parentId == null) parentId = "";
            if (sortId == null) sortId = "";

            Routes routes = new Routes();
            routes.setPath(path);
            routes.setName(name);
            routes.setComponent(component);
            routes.setComponentPath(componentPath);
            routes.setDescription(description);
            routes.setLevel(level);
            routes.setParentId(parentId);
            routes.setSortId(sortId);
            if (isRedirect != null) routes.setIsRedirect(isRedirect);
            if (isNavigation != null) routes.setIsNavigation(isNavigation);
            routes.setUpdateTime(LocalDateTime.now());
            routes.setUpdateUserId(BaseContext.getCurrentId());
            routes.setSystemCode(s.getSystemCode());

            //路由id不存在则创建
            if (routeId == null) {
                routes.setCreateUserId(BaseContext.getCurrentId());
                this.save(routes);
                return Result.success("创建路由成功！");
            }
            //路由id存在则更新
            routes.setId(routeId);
            this.updateById(routes);
            return Result.success("更新路由成功！");
        } catch (Exception e) {
            log.error("创建或更新路由失败！{}", e.getMessage());
            throw new ProgramException();
        }
    }

    /**
     * 批量删除页面路由
     *
     * @param routeIdList 权限id列表
     * @return s
     */
    @Override
    public Result<String> deleteRoutes(List<String> routeIdList) {
        try {
            if (routeIdList.isEmpty()) return Result.error("请选择要删除的页面路由");

            LambdaUpdateWrapper<Routes> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(Routes::getIsDelete, 1);
            updateWrapper.set(Routes::getDeleteUserId, BaseContext.getCurrentId());
            updateWrapper.set(Routes::getDeleteTime, LocalDateTime.now());
            updateWrapper.in(Routes::getId, routeIdList);

            this.update(updateWrapper);
            return Result.success("删除路由页面成功！");
        } catch (Exception e) {
            log.error("删除路由页面失败！{}", e.getMessage());
            throw new ProgramException();
        }
    }

    /**
     * 批量更新路由状态
     *
     * @param routeIdList 路由id 列表
     * @param status      状态 0启用，1禁用
     * @return s
     */
    @Override
    public Result<String> updateRoutesStatus(List<String> routeIdList, Integer status) {
        try {
            if (routeIdList.isEmpty() || status == null) return Result.error("请将参数补充完整");
            if (status < 0 || status > 1) return Result.error("状态参数错误");

            LambdaUpdateWrapper<Routes> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(Routes::getEnable, status);
            updateWrapper.set(Routes::getUpdateUserId, BaseContext.getCurrentId());
            updateWrapper.set(Routes::getUpdateTime, LocalDateTime.now());
            updateWrapper.in(Routes::getId, routeIdList);

            this.update(updateWrapper);
            return Result.success("更新角色状态成功！");
        } catch (Exception e) {
            log.error("更新路由状态失败！{}", e.getMessage());
            throw new ProgramException();
        }
    }
}
